package net.ib.mtalk.ui.buddy.talk;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.protobuf.micro.InvalidProtocolBufferMicroException;

import net.ib.mntalk.protocol.Common.BuddyInfo;
import net.ib.mntalk.protocol.Common.Calendar;
import net.ib.mtalk.R;
import net.ib.mtalk.constant.MTalkConstant;
import net.ib.mtalk.database.DatabaseContract.BuddyTable;
import net.ib.mtalk.database.DatabaseContract.GroupTable;
import net.ib.mtalk.database.DatabaseContract.ParticipantsTable;
import net.ib.mtalk.database.helper.GroupDatabaseHelper;
import net.ib.mtalk.global.GlobalPreferences;
import net.ib.mtalk.ui.buddy.item.BuddyTalkGroupItem;
import net.ib.mtalk.ui.buddy.item.BuddyUUIDItem;
import net.ib.mtalk.ui.buddy.item.ChildrenItem;
import net.ib.mtalk.ui.buddy.item.GroupItem;
import net.ib.mtalk.ui.favorite.FavoriteListCursorAdapter;
import net.ib.mtalk.util.GpbSupport;
import net.ib.mtalk.util.ProfileImageLoader;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.ContactsContract.Contacts;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class BuddyTalkExpandableListAdapter extends BaseExpandableListAdapter{

	/**
	 * Group layout id
	 */
	private int mGroupLayout;
	private int mChildLayout;
	private Context mContext;
	private boolean mShowcheckbox = false;
	
	private List<GroupItem> mArr_group;
	private List<List<ChildrenItem>> mArr_child;
	private List<Integer> item_groups = new ArrayList<Integer>();
	private List<BuddyUUIDItem> item_partispants;
	
    private LayoutInflater mInflater;
    
    public BuddyTalkExpandableListAdapter(Context context, int grouplayout, int childlayout, boolean showcheckbox, List<GroupItem> arr_group, List<List<ChildrenItem>> arr_child, List<BuddyUUIDItem> item_partispants){
    	mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    	mGroupLayout = grouplayout;
    	mChildLayout = childlayout;
    	mContext = context;
    	mShowcheckbox = showcheckbox;
    	this.mArr_group = arr_group;
    	this.mArr_child = arr_child;
    	this.item_partispants = item_partispants;
    }
    
	@Override
	public Object getChild(int groupPosition, int childPosition) {
		return mArr_child.get(groupPosition).get(childPosition);
	}
	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}
	
	@Override
	public View getChildView(final int groupPosition, final int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		ChildViewHolder childViewHolder = null;
        if (convertView == null) {
            convertView = mInflater.inflate(mChildLayout, parent, false);
            childViewHolder = new ChildViewHolder((LinearLayout)convertView, mShowcheckbox);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
		childViewHolder.name.setText(mArr_child.get(groupPosition).get(childPosition).nick);
		childViewHolder.statusMsg.setText(mArr_child.get(groupPosition).get(childPosition).status);
		
		final BuddyUUIDItem item = new BuddyUUIDItem(mArr_child.get(groupPosition).get(childPosition).msb, 
											mArr_child.get(groupPosition).get(childPosition).lsb,
											mArr_child.get(groupPosition).get(childPosition).name);
		if(item_partispants.contains(item)){
			childViewHolder.checkBox.setChecked(true);
		} else {
			childViewHolder.checkBox.setChecked(false);
		}
		
		childViewHolder.checkBox.setOnClickListener(childChkListener());
		childViewHolder.checkBox.setTag(item);
		
		ProfileImageLoader.getInstance(mContext).loadProfileImage(childViewHolder.profile, 
				GpbSupport.UuidMsgToString(GpbSupport.makeUuidMsg(mArr_child.get(groupPosition).get(childPosition).msb, mArr_child.get(groupPosition).get(childPosition).lsb)));
		
		childViewHolder.profile.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				File file = new File(MTalkConstant.MTALK_PATH + "/buddy/" + GpbSupport.UuidMsgToString(GpbSupport.makeUuidMsg(mArr_child.get(groupPosition).get(childPosition).msb, mArr_child.get(groupPosition).get(childPosition).lsb)));
				if(!file.exists() || mArr_child.get(groupPosition).get(childPosition).buddyInfo.getProfile().getProfileImage() == null || mArr_child.get(groupPosition).get(childPosition).buddyInfo.getProfile().getProfileImage().getFileName().equals("null")){
					return;
				}
				Intent intent = new Intent(mContext, ProfileImageView.class);
				intent.putExtra("msb", mArr_child.get(groupPosition).get(childPosition).lsb);
				intent.putExtra("lsb", mArr_child.get(groupPosition).get(childPosition).name);
				mContext.startActivity(intent);
			}
		});
		
		if(mArr_child.get(groupPosition).get(childPosition).buddyInfo.getProfile().getBirthday() != null &&
				mArr_child.get(groupPosition).get(childPosition).buddyInfo.getProfile().getBirthday().getDay() != -1){
			FavoriteListCursorAdapter.birthCheck(childViewHolder.birth_image, mArr_child.get(groupPosition).get(childPosition).buddyInfo.getProfile().getBirthday());
		} else {
			childViewHolder.birth_image.setVisibility(View.GONE);
		}
		
		convertView.setTag(childViewHolder);
        
        return convertView;
	}
	

	@Override
	public int getChildrenCount(int groupPosition) {
		return mArr_child.get(groupPosition).size();
	}

	@Override
	public Object getGroup(int groupPosition) {
		return mArr_group.get(groupPosition);
	}

	@Override
	public int getGroupCount() {
		return mArr_group.size();
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
		GroupViewHolder holder = null;
		if (convertView == null) {
			convertView = mInflater.inflate(mGroupLayout, parent, false);
			holder = new GroupViewHolder((LinearLayout)convertView, mShowcheckbox);
		} else {
			holder = (GroupViewHolder)convertView.getTag();
		}
		
		if(isExpanded) {
			holder.foldBtn.setBackgroundResource(R.drawable.mn_folding);
		}
		else {
			holder.foldBtn.setBackgroundResource(R.drawable.mn_unfolding);
		}
		
		GroupItem item = (GroupItem)getGroup(groupPosition);
		
		// fold 상태값을 저장
		GroupDatabaseHelper.changeFold(mContext, item.id, isExpanded);
		
		holder.groupTextView.setText(item.name);
		holder.participantsTextView.setText("(" + getChildrenCount(groupPosition) + ")");
		/*if(getChildrenCount(groupPosition) == 0 && item.id == 1){
			holder.item.setVisibility(View.GONE);
		}*/
		
		if(item_groups.contains(item.id)){
			holder.chBox.setChecked(true);
		} else {
			holder.chBox.setChecked(false);
		}
		
		holder.chBox.setOnClickListener(groupChkListener(groupPosition));
		holder.chBox.setTag(item.id);

        convertView.setTag(holder);
        return convertView;
	}

	@Override
	public boolean hasStableIds() {
		return true;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return true;
	}
	
	
	private static class ChildViewHolder {
		CheckBox checkBox;
		ImageView profile;
		ImageView birth_image;
		TextView name;
		TextView statusMsg;
		ImageView relation;
		LinearLayout item;
		
		public ChildViewHolder(LinearLayout item, boolean showcheckbox) {
			checkBox = (CheckBox)item.findViewById(R.id.buddy_child_check);
			profile = (ImageView)item.findViewById(R.id.buddy_child_profile);
			birth_image = (ImageView)item.findViewById(R.id.buddy_birthday_img);
			name = (TextView)item.findViewById(R.id.buddy_child_name);
			statusMsg = (TextView)item.findViewById(R.id.buddy_child_status_msg);
			relation = (ImageView)item.findViewById(R.id.buddy_relation_img);
			this.item = item;
			
			if(showcheckbox){
				checkBox.setVisibility(View.VISIBLE);
			} else{
				checkBox.setVisibility(View.GONE);
			}
		}
	}
	
	private static class GroupViewHolder {
		CheckBox chBox;
		TextView groupTextView;
		TextView participantsTextView;
		ImageView foldBtn;
		LinearLayout item;
		
		public GroupViewHolder(LinearLayout item, boolean showcheckbox) {
			chBox = (CheckBox) item.findViewById(R.id.buddy_group_chk);
			groupTextView = (TextView)item.findViewById(R.id.buddy_group_name);
			participantsTextView = (TextView)item.findViewById(R.id.buddy_group_participants);
			foldBtn = (ImageView)item.findViewById(R.id.buddy_group_fold);
			this.item = item;
			
			if(showcheckbox){
				chBox.setVisibility(View.VISIBLE);
			} else{
				chBox.setVisibility(View.GONE);
			}
		}
	}
	
	public static void createDataSet(Context context, List<GroupItem> group, List<List<ChildrenItem>> child) {
		createGroup(context, group, child);
	}

	private static void createGroup(Context context, List<GroupItem> group, List<List<ChildrenItem>> child) {
		addNewGroup(context, group, child);
		Cursor cursor = context.getContentResolver().query(GroupTable.CONTENT_URI, GroupTable.PROJECTION, GroupTable._ID + ">2", null, GroupTable.KEY_GROUP_NAME);
		
		try{
			while(cursor.moveToNext()){
				List<ChildrenItem> childComponent = new ArrayList<ChildrenItem>();
				int group_id = cursor.getInt(cursor.getColumnIndexOrThrow(GroupTable._ID));
				int fold = cursor.getInt(cursor.getColumnIndexOrThrow(GroupTable.KEY_GROUP_SET_FOLD));
				group.add(new GroupItem(group_id, cursor.getString(cursor.getColumnIndexOrThrow(GroupTable.KEY_GROUP_NAME)), fold));
				
				String sortOrder = "case"+
				  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'ㄱ' AND '힣'  then 1 "+
				  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'A' AND 'Z' then 2 "+  
				  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'a' AND 'z' then 3 "+           
				  " else 4 end, "+BuddyTable.KEY_BUDDY_DISPLAYNICK + " COLLATE LOCALIZED ASC";  //ASC로 하면 ㄱ,ㄴ초성으로 되어 있는 한글이 먼저 정렬됨
				Cursor cursor2 = context.getContentResolver().query(ParticipantsTable.buildBuddyGroupUri(), null, ParticipantsTable.KEY_PARTICIPANTS_GROUP + "=?", 
						new String[]{String.valueOf(group_id)}, sortOrder);
				try{
					while(cursor2.moveToNext()){
						BuddyInfo buddyInfo = BuddyInfo.parseFrom(cursor2.getBlob(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
						childComponent.add(
								new ChildrenItem(cursor2.getInt(cursor2.getColumnIndexOrThrow(ParticipantsTable.KEY_PARTICIPANTS_BUDDY)), 
												 GpbSupport.msbOf(buddyInfo.getUserUuid()), 
												 GpbSupport.lsbOf(buddyInfo.getUserUuid()), 
												 buddyInfo.getName().getDisplayName(),
												 buddyInfo.getNick().getDisplayName(),
												 buddyInfo.getProfile().getStatus(),
												 cursor2.getInt(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE)), 
												 buddyInfo));
					}
				} catch (InvalidProtocolBufferMicroException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} finally {
					cursor2.close();
				}
				child.add(childComponent);
			}
		} finally {
			cursor.close();
		}
		addNotAssinged(context, group, child);
	}
	
	private static void addNewGroup(Context context, List<GroupItem> group, List<List<ChildrenItem>> child) {
		Cursor cursor = context.getContentResolver().query(GroupTable.CONTENT_URI, GroupTable.PROJECTION, GroupTable._ID + "='1'", null, null);
		int fold = 0;
		try{
			while(cursor.moveToNext()){
				fold = cursor.getInt(cursor.getColumnIndexOrThrow(GroupTable.KEY_GROUP_SET_FOLD));
			}
			group.add(new GroupItem(1, context.getString(R.string.buddy_new_buddy), fold));
		} finally{
			cursor.close();
		}
		String[] projection = {BuddyTable._ID, BuddyTable.KEY_BUDDY_FAVORITE, BuddyTable.KEY_BUDDY_INFO};
		String selection = BuddyTable.KEY_BUDDY_STATUS_TYPE + "='1' AND " + BuddyTable.KEY_BUDDY_NEW_FRIEND + "='1'";
		
		String sortOrder = "case"+
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'ㄱ' AND '힣'  then 1 "+
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'A' AND 'Z' then 2 "+  
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'a' AND 'z' then 3 "+           
		  " else 4 end, "+BuddyTable.KEY_BUDDY_DISPLAYNICK + " COLLATE LOCALIZED ASC";  //ASC로 하면 ㄱ,ㄴ초성으로 되어 있는 한글이 먼저 정렬됨

		Cursor cursor_new_group = context.getContentResolver().query(BuddyTable.CONTENT_URI, projection, selection, null, sortOrder);
		if(cursor_new_group.getCount() == 0){
			group.clear();
			cursor_new_group.close();
			return;
		}
		List<ChildrenItem> childComponent = new ArrayList<ChildrenItem>();
		try{
			while(cursor_new_group.moveToNext()){
				BuddyInfo buddyInfo = BuddyInfo.parseFrom(cursor_new_group.getBlob(cursor_new_group.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
				childComponent.add(
						new ChildrenItem(cursor_new_group.getInt(cursor_new_group.getColumnIndexOrThrow(BuddyTable._ID)), 
										 GpbSupport.msbOf(buddyInfo.getUserUuid()), 
										 GpbSupport.lsbOf(buddyInfo.getUserUuid()), 
										 buddyInfo.getName().getDisplayName(),
										 buddyInfo.getNick().getDisplayName(),
										 buddyInfo.getProfile().getStatus(),
										 cursor_new_group.getInt(cursor_new_group.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE)), 
										 buddyInfo));
			}
		} catch (InvalidProtocolBufferMicroException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally{
			cursor_new_group.close();
		}
		child.add(childComponent);
	}

	private static void addNotAssinged(Context context, List<GroupItem> group, List<List<ChildrenItem>> child) {
		Cursor cursor = context.getContentResolver().query(GroupTable.CONTENT_URI, GroupTable.PROJECTION, GroupTable._ID + "='2'", null, null);
		int fold = 0;
		try{
			while(cursor.moveToNext()){
				fold = cursor.getInt(cursor.getColumnIndexOrThrow(GroupTable.KEY_GROUP_SET_FOLD));
			}
			group.add(new GroupItem(1, context.getString(R.string.group_not_assigned), fold));
		} finally{
			cursor.close();
		}
		String[] projection = {BuddyTable._ID, BuddyTable.KEY_BUDDY_FAVORITE, BuddyTable.KEY_BUDDY_INFO};
		String selection = BuddyTable.KEY_BUDDY_STATUS_TYPE + "='1'";
		
		String sortOrder = "case"+
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'ㄱ' AND '힣'  then 1 "+
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'A' AND 'Z' then 2 "+  
		  " when substr("+BuddyTable.KEY_BUDDY_DISPLAYNICK+", 1, 1) BETWEEN 'a' AND 'z' then 3 "+           
		  " else 4 end, "+BuddyTable.KEY_BUDDY_DISPLAYNICK + " COLLATE LOCALIZED ASC";  //ASC로 하면 ㄱ,ㄴ초성으로 되어 있는 한글이 먼저 정렬됨

		Cursor cursor_not_group = context.getContentResolver().query(BuddyTable.buildBuddyNotGroupUri(), projection, selection, null, sortOrder);
		List<ChildrenItem> childComponent = new ArrayList<ChildrenItem>();
		try{
			while(cursor_not_group.moveToNext()){
				BuddyInfo buddyInfo = BuddyInfo.parseFrom(cursor_not_group.getBlob(cursor_not_group.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
				childComponent.add(
						new ChildrenItem(cursor_not_group.getInt(cursor_not_group.getColumnIndexOrThrow(BuddyTable._ID)), 
										 GpbSupport.msbOf(buddyInfo.getUserUuid()), 
										 GpbSupport.lsbOf(buddyInfo.getUserUuid()), 
										 buddyInfo.getName().getDisplayName(),
										 buddyInfo.getNick().getDisplayName(),
										 buddyInfo.getProfile().getStatus(),
										 cursor_not_group.getInt(cursor_not_group.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE)), 
										 buddyInfo));
			}
		} catch (InvalidProtocolBufferMicroException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally{
			cursor_not_group.close();
		}
		child.add(childComponent);
	}

	private OnClickListener childChkListener() {
		OnClickListener listener = new OnClickListener() {
			@Override
			public void onClick(View v) {
				BuddyUUIDItem item = (BuddyUUIDItem) v.getTag();
				if(!item_partispants.contains(item)) {
					item_partispants.add(item);
				} else {
					item_partispants.remove(item);
				}
				notifyDataSetChanged();
			}
		};
		return listener;
	}
	
	private OnClickListener groupChkListener(final int groupPosition){
		OnClickListener listener = new OnClickListener() {
			@Override
			public void onClick(View v) {
				Integer id = (Integer) v.getTag();
				if(!item_groups.contains(id)){
					item_groups.add(id);
					int count = getChildrenCount(groupPosition);
					for(int i = 0 ; i < count ; i++){
						ChildrenItem item = (ChildrenItem) getChild(groupPosition, i);
						BuddyUUIDItem uuidItem = new BuddyUUIDItem(item.msb, item.lsb, item.name);
						if(!item_partispants.contains(uuidItem)) {
							item_partispants.add(uuidItem);
						}
					}
					notifyDataSetChanged();
				} else {
					item_groups.remove(id);
					int count = getChildrenCount(groupPosition);
					for(int i = 0 ; i < count ; i++){
						ChildrenItem item = (ChildrenItem) getChild(groupPosition, i);
						BuddyUUIDItem uuidItem = new BuddyUUIDItem(item.msb, item.lsb, item.name);
						if(item_partispants.contains(uuidItem)) {
							item_partispants.remove(uuidItem);
						}
					}
					notifyDataSetChanged();
				}
			}
		};
		return listener;
	}
}
